package com.me.study.concurrent.threadPool;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 这是一个线程池测试类：测试线程池 API
 *
 * @Title: com.me.concurrent.thread.TestThreadPool
 * @author ME
 * @date 2018年9月7日 下午3:55:52
 */
public class TestThreadPool {

	public static void main(String[] args) {
		// ExecutorService cachedThreadPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS,
			new SynchronousQueue<>());
		threadPool.allowCoreThreadTimeOut(true);
		try {
			MyThead t1 = new MyThead("t1", 5000);
			MyThead t2 = new MyThead("t2", 1000);
			MyThead t3 = new MyThead("t3", 3000);

			// Future<String> futureCard = threadPool.submit(t1);
			// Future<String> futureCode = threadPool.submit(t2);
			// shutdown 之后就禁止添加新任务，
			// threadPool.shutdown();
			// String result1 = futureCard.get();
			// String result2 = futureCode.get();

			// 通过 invokeAll 批量提交任务，会阻塞主线程
			List<MyThead> tasks = new ArrayList<>();
			tasks.add(t1);
			tasks.add(t2);
			tasks.add(t3);
			List<Future<String>> futures = threadPool.invokeAll(tasks);

			System.out.println("11111");
		// } catch (InterruptedException e) {
		// 	e.printStackTrace();
		// } catch (ExecutionException e) {
		// 	e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 如果前面线程池被 shutdown()，此处会拒绝任务异常 RejectedExecutionException
		final Exchanger<String> exchanger = new Exchanger<String>();
		threadPool.execute(new Runnable() {
			@Override
			public void run() {
				String aaaa = "aaaaaaaaaa";
				try {
					String bbbb = exchanger.exchange(aaaa);
					System.out.println(aaaa + " ---> " + bbbb);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});

		threadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					String bbbb = "bbbbbbbb";
					String aaaa = exchanger.exchange(bbbb);
					System.out.println("a is " + aaaa + " , b is " + bbbb);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
		});

		// SleepUtil.seconds(20);// 睡眠之后可以看到核心线程数被回收的过程
		threadPool.shutdown();
	}

	public static class MyThead implements Callable<String> {

		private String name;
		private long waitTime;

		public MyThead(String name, int timeInMillis) {
			this.name = name;
			this.waitTime = timeInMillis;
		}

		@Override
		public String call() throws Exception {
			Thread.currentThread().setName(name);
			Thread.sleep(waitTime);
			System.out.println(name);
			return Thread.currentThread().getName();
		}
	}
}
